package com.runa.monitor.platinterface.netservice.equipment.dtu.fourG;

import com.alibaba.fastjson.JSON;
import com.runa.monitor.comm.dto.Node;
import com.runa.monitor.comm.dto.Point;
import com.runa.monitor.comm.dto.newComm.ValveVO;
import com.runa.monitor.platinterface.backwork.impl.RccTaskFunction;
import com.runa.monitor.platinterface.backwork.impl.SubEquReadTaskFunction;
import com.runa.monitor.platinterface.backwork.impl.SubEquWriteTaskFunction;
import com.runa.monitor.platinterface.mqtt.MqttUtil;
import com.runa.monitor.platinterface.netservice.equipment.dtu.FourGDtuTaskFunction;
import com.runa.monitor.platinterface.netservice.equipment.dtu.MqttModbusDriver;
import com.runa.monitor.platinterface.netservice.equipment.dtu.point.FourGValvePoints;
import com.runa.monitor.platinterface.netservice.equipment.dtu.point.ModbusPoints;
import com.runa.persistence.util.LogUtil;
import com.runa.protocol.dto.ModbusPoint;
import com.runa.protocol.dto.ModbusResponseData;
import com.runa.protocol.enums.ByteOrder;
import com.runa.protocol.enums.ModbusDataType;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.netservice.dtu.DtuResponse;
import com.runa.rccprotocol.netservice.dtu.ModbusRtuResponse;
import com.runa.rccprotocol.netservice.modbus.ModbusRequest;
import com.runa.rccprotocol.task.FourGValveTask;
import com.runa.rccprotocol.task.FourGValveWriteTask;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 2024/9/11 11:33
 * zhangYB
 */
@Slf4j
public class FourGValveDtuDriver extends MqttModbusDriver {

    public FourGValveDtuDriver() {
        this("", 30000, new FourGValvePoints());
    }

    public FourGValveDtuDriver(String serial, Integer timeout, ModbusPoints points) {
        super(serial, timeout, points);
    }

    public void readPoints(FourGValveTask task) {
        Node node = task.getNode();
        SubEquReadTaskFunction subEquReadTaskFunction = new SubEquReadTaskFunction(task.getTask(), null, task.getHoldInfo(), task.getPriority());
        subEquReadTaskFunction.setStatus(Collections.singletonList(node));
        int slaveId = task.getSlaveId();
        List<List<ModbusPoint>> sections = allPoints.getSections();
        FourGDtuTaskFunction fourGDtuTaskFunction = new FourGDtuTaskFunction(subEquReadTaskFunction, node, sections.size());
        log.debug("{} 请求 {} 次", node.getSerial(), sections.size());
        for (int i = 0; i < sections.size(); i++) {
            List<ModbusPoint> modbusPoints = sections.get(i);
            ModbusRequest modbusRequest = new ModbusRequest(serial());
            modbusRequest.setModbusPoints(modbusPoints);
            modbusRequest.readFourGModbusData(slaveId);
            log.debug("4G阀 {} {} 请求 {}", node.getId(), node.getSerial(), ByteUtil.byteToHexString(modbusRequest.getData()));
            LogUtil.getLogAndInfo(node.getSerial(), "4G阀", "{} 发送: {} topic: {}", node.getSerial(), ByteUtil.byteToHexString(modbusRequest.getData()), fourGDtuTaskFunction.getTopic());
            sendRequest(modbusRequest, fourGDtuTaskFunction);
        }
    }

    public static void main(String[] args) throws Exception {
        FourGValvePoints fourGValvePoints = new FourGValvePoints();
        Point point = fourGValvePoints.getByCode("actOpen");
        ModbusPoint modbusPoint = new ModbusPoint(point.getId(), point.getCode(), ModbusDataType.valuesOf(point.getDataType()),
                Integer.valueOf(point.getAddress()), ByteOrder.valueOf(point.getByteOrder()), point.getOffset());
        switch (modbusPoint.getDataType()) {
            case Modbus_Int16:
            case Modbus_UInt16:
                byte[] writeData = ByteUtil.shortToByte(Float.valueOf("33").shortValue(), modbusPoint.getByteOrder());
                System.out.println(ByteUtil.byteToHexString(writeData));
                ModbusRequest modbusRequest = new ModbusRequest("");
                modbusRequest.writeFourGModbusData(0xfe, modbusPoint.getRegisterAddress(), writeData);
                System.out.println(ByteUtil.byteToHexString(modbusRequest.getData()));
                break;
            case Modbus_Float:
                writeData = ByteUtil.floatToByte(Float.valueOf("33"), modbusPoint.getByteOrder());
                System.out.println(ByteUtil.byteToHexString(writeData));
            default:
        }

    }

    public void writePoints(FourGValveWriteTask task) {
        try {
            String code = task.getCode();
            FourGValvePoints fourGValvePoints = (FourGValvePoints)allPoints;
            Point point = fourGValvePoints.getByCode(code);
            if (null != point) {
                Node node = task.getNode();
                SubEquWriteTaskFunction subEquWriteTaskFunction = new SubEquWriteTaskFunction(task.getTask(), task.getHoldInfo(), task.getPriority());
                subEquWriteTaskFunction.setStatus(node);
                int slaveId = task.getSlaveId();
                ModbusPoint modbusPoint = new ModbusPoint(point.getId(), point.getCode(), ModbusDataType.valuesOf(point.getDataType()),
                        Integer.valueOf(point.getAddress()), ByteOrder.valueOf(point.getByteOrder()), point.getOffset());
                byte[] writeData = getWriteData(modbusPoint, task.getValue());
                FourGDtuTaskFunction fourGDtuTaskFunction = new FourGDtuTaskFunction(subEquWriteTaskFunction, node, 1, false);
                ModbusRequest modbusRequest = new ModbusRequest(serial());
                modbusRequest.writeFourGModbusData(slaveId, modbusPoint.getRegisterAddress(), writeData);
                log.debug("4G阀 {} {} 下发 {}", node.getId(), node.getSerial(), ByteUtil.byteToHexString(modbusRequest.getData()));
                String topic = "/RU-VC-05/" + node.getSerial() + "/down";
                LogUtil.getLogAndInfo(node.getSerial(), "4G阀", "{} 发送: {} topic: {}", node.getSerial(), ByteUtil.byteToHexString(modbusRequest.getData()), topic);
                sendRequest(modbusRequest, fourGDtuTaskFunction);
            }
        } catch (Exception e) {
            log.error("", e);
        }

    }


    public byte[] getWriteData(ModbusPoint modbusPoint, String value) {
        switch (modbusPoint.getDataType()) {
            case Modbus_Int16:
            case Modbus_UInt16:
                return ByteUtil.shortToByte(Float.valueOf(value).shortValue(), modbusPoint.getByteOrder());
            case Modbus_Float:
                return ByteUtil.floatToByte(Float.valueOf(value), modbusPoint.getByteOrder());
            default:
        }
        return new byte[0];
    }


    @Override
    public void receiveDtuResponse(DtuResponse dtuResponse) {
        if (requestTask.getTaskFunction() instanceof FourGDtuTaskFunction) {
            FourGDtuTaskFunction taskFunction = (FourGDtuTaskFunction) requestTask.getTaskFunction();
            log.debug("4G阀dtuResponse: {}", JSON.toJSONString(dtuResponse));
            if (dtuResponse instanceof ModbusRtuResponse) {
                ModbusRtuResponse modbusRtuResponse = (ModbusRtuResponse)dtuResponse;
                ModbusResponseData modbusResponse = modbusRtuResponse.getModbusResponse();
                log.debug("4G阀modbusRtuResponse data: {}", ByteUtil.byteToHexString(modbusResponse.getData()));
                taskFunction.addResponse(modbusRtuResponse);
                LogUtil.getLogAndInfo(taskFunction.getSerial(), "4G阀","{} canRequest: {} isTailFrame: {}", dtuResponse.getAddress(), taskFunction.canRequest(), taskFunction.isTailFrame());
                if (taskFunction.canRequest()) {
                    mockUnlock();
                }
                if (taskFunction.isTailFrame()) {
                    taskFunction.setFourGValvePoints((FourGValvePoints)allPoints);
                    taskFunction.finish();
                }
            }
        }

    }



}
